package com.yunc.common.tio;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yunc.common.utils.SpringContextUtils;
import com.yunc.modules.cms.entity.CircleContent;
import com.yunc.modules.cms.service.ICircleContentService;
import com.yunc.modules.sys.entity.SysUserToken;
import com.yunc.modules.sys.service.ISysUserTokenService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsResponse;
import org.tio.websocket.common.WsSessionContext;
import org.tio.websocket.server.handler.IWsMsgHandler;

import java.util.List;
import java.util.Objects;

/**
 * @author tanyaowu
 * 2017年6月28日 下午5:32:38
 */
public class ShowcaseWsMsgHandler implements IWsMsgHandler {
	private static Logger log = LoggerFactory.getLogger(ShowcaseWsMsgHandler.class);

	public static final ShowcaseWsMsgHandler me = new ShowcaseWsMsgHandler();

	private final static ISysUserTokenService sysUserTokenService = (ISysUserTokenService) SpringContextUtils.getBean("sysUserTokenService");

	private final static ICircleContentService circleContentService = (ICircleContentService) SpringContextUtils.getBean("circleContentService");

	private ShowcaseWsMsgHandler() {

	}

	/**
	 * 握手时走这个方法，业务可以在这里获取cookie，request参数等
	 */
	@Override
	public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
		String clientip = request.getClientIp();
		log.info("收到来自{}的ws握手包\r\n{}", clientip, request.toString());
		return httpResponse;
	}

	/** 
	 * @param httpRequest
	 * @param httpResponse
	 * @param channelContext
	 * @throws Exception
	 * @author tanyaowu
	 */
	@Override
	public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
		// 绑定到群组，后面会有群发
		Tio.bindGroup(channelContext, "showcase-websocket");
		String token = httpRequest.getParam("token");
		SysUserToken tokenEntity = sysUserTokenService.getOne(new QueryWrapper<SysUserToken>().eq("token", token));
		if (tokenEntity == null) {
			return;
		}
		Tio.bindUser(channelContext, String.valueOf(tokenEntity.getUserId()));
		int count = Tio.getAllChannelContexts(channelContext.groupContext).getObj().size();
		String msg = channelContext.getClientNode().toString() + " 进来了，现在共有【" + count + "】人在线";
		// 用tio-websocket，服务器发送到客户端的Packet都是WsResponse
		WsResponse wsResponse = WsResponse.fromText(msg, "utf-8");
		// 群发
		// Tio.sendToGroup(channelContext.groupContext, "showcase-websocket", wsResponse);
	}

	/**
	 * 字节消息（binaryType = arraybuffer）过来后会走这个方法
	 */
	@Override
	public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		return null;
	}

	/**
	 * 当客户端发close flag时，会走这个方法
	 */
	@Override
	public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		Tio.remove(channelContext, "receive close flag");
		return null;
	}

	/**
	 * 字符消息（binaryType = blob）过来后会走这个方法
	 *
	 * 如果进入后不绑定bindUser直接走这个方法，导致的结果就是不能正常接收消息
	 * 历史记录怎么查看问题
	 */
	@Override
	public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {
		WsSessionContext wsSessionContext = (WsSessionContext) channelContext.getAttribute();
		// 获取websocket握手包
		HttpRequest httpRequest = wsSessionContext.getHandshakeRequestPacket();
		if (log.isDebugEnabled()) {
			log.debug("握手包:{}", httpRequest);
		}
		/*if (Objects.equals("心跳内容", text)) {
			log.info("心跳内容...");
			return null;
		}*/
		// text取出来
		JSONObject object = JSON.parseObject(text);
		String circleContentId = (String) object.get("circleContentId");
		long id = 0;
		if (StringUtils.isNotEmpty(circleContentId)) {
			id = Long.parseLong(circleContentId);
		}
		List<CircleContent> circleContentList = circleContentService.listSize(id, 5);

		String msg = JSON.toJSONString(circleContentList);
		//用tio-websocket，服务器发送到客户端的Packet都是WsResponse
		WsResponse wsResponse = WsResponse.fromText(msg, "utf-8");
		//群发
		Tio.sendToGroup(channelContext.groupContext, "showcase-websocket", wsResponse);
		/*String token = (String) object.get("token");
		SysUserToken sysUserToken = new SysUserToken();
		// 根据accessToken，查询用户信息
		SysUserToken tokenEntity = sysUserTokenService.getOne(new QueryWrapper<SysUserToken>().eq("token", token));
		text = (String) object.get("content");
		log.info("收到ws消息:{}", text);
		String msg = tokenEntity.getUserId() + " 说：" + text;
		String s = "{\"username\":\"%s\",\"avatar\":\"%s\",\"id\":\"%s\",\"type\":\"%s\",\"content\":\"%s\"}";
		//用tio-websocket，服务器发送到客户端的Packet都是WsResponse
		WsResponse wsResponse = WsResponse.fromText(String.format(s, tokenEntity.getUserId(), "http://tp1.sinaimg.cn/1571889140/180/40030060651/1",
				tokenEntity.getUserId(), "friend", msg), "utf-8");
		// 绑定用户ID
		Tio.bindUser(channelContext, String.valueOf(tokenEntity.getUserId()));
		Tio.sendToUser(channelContext.groupContext, toUserId, wsResponse);*/
		// 返回值是要发送给客户端的内容，一般都是返回null
		return null;
	}

}
